package hn.cch.https;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
import io.netty.handler.ssl.SslContext;
import io.netty.handler.ssl.SslContextBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.net.ssl.SSLException;
import java.io.File;

/**
 * HTTP服务器
 */

public class HttpsServer implements Runnable {

    private static Logger logger = LoggerFactory.getLogger(HttpsServer.class);




    private int port;

    public HttpsServer(int port) {
        this.port = port;
        logger.info("http server port : " + port);
    }

    public int getPort() {
        return port;
    }

    public void setPort(int port) {
        this.port = port;
    }

    private void bind() {

        ServerBootstrap server = new ServerBootstrap();
        EventLoopGroup parentGroup = new NioEventLoopGroup(1);//使用一个线程处理连接
        EventLoopGroup childGroup = new NioEventLoopGroup();//0：使用线程池处理读写，线程个数是CPU核心数*2（CPU线程数）
        server.group(parentGroup, childGroup);
        server.channel(NioServerSocketChannel.class);//设置非阻塞通道

        server.option(ChannelOption.SO_BACKLOG, 1024);//设置最大连接数
        server.childOption(ChannelOption.SO_KEEPALIVE, true);//设置长连接模式

        /**
         netty框架实现http服务器的方式:
         class HttpChannel extends ChannelInboundHandlerAdapter
         使用HttpContent的默认大小传输和利用LastHttpContent标记最后一个
         */
        server.handler(new LoggingHandler(LogLevel.DEBUG));
        server.childHandler(new HttpsChannel());

        try {
            ChannelFuture channelFuture = server.bind(port).sync();
            channelFuture.channel().closeFuture().sync();
        } catch (InterruptedException e) {
            logger.error("http server error : " + e.getMessage());
            System.exit(-1);//服务器启动失败|程序异常终止退出
        } finally {
            childGroup.shutdownGracefully();
            parentGroup.shutdownGracefully();
        }
    }

    @Override
    public void run() {
        this.bind();//使用一个单独的线程启动服务器
    }
}
